all repos — caroster @ 5ecddb30cd1351970186d1d7939cad57554ce781

[Octree] Group carpool to your event https://caroster.io

frontend/pages/e/[uuid].tsx (view raw)

  1import {useState, useReducer, useEffect} from 'react';
  2import {useTranslation} from 'react-i18next';
  3import Layout from '../../layouts/Default';
  4import Fab from '../../containers/Fab';
  5import CarColumns from '../../containers/CarColumns';
  6import NewCarDialog from '../../containers/NewCarDialog';
  7import AddToMyEventDialog from '../../containers/AddToMyEventDialog';
  8import EventBar from '../../containers/EventBar';
  9import useToastStore from '../../stores/useToastStore';
 10import {initializeApollo} from '../../lib/apolloClient';
 11import ErrorPage from '../_error';
 12import {
 13  useUpdateEventMutation,
 14  Event as EventType,
 15  useEventByUuidQuery,
 16  EventByUuidDocument,
 17} from '../../generated/graphql';
 18import useEventStore from '../../stores/useEventStore';
 19import Loading from '../../containers/Loading';
 20
 21const POLL_INTERVAL = 10000;
 22
 23interface Props {
 24  event: EventType;
 25  eventUUID: string;
 26}
 27
 28const EventPage = props => {
 29  const {event} = props;
 30  const {t} = useTranslation();
 31
 32  if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
 33
 34  return <Event {...props} />;
 35};
 36
 37const Event = (props: Props) => {
 38  const {eventUUID} = props;
 39  const {t} = useTranslation();
 40  const addToast = useToastStore(s => s.addToast);
 41  const setEvent = useEventStore(s => s.setEvent);
 42  const eventUpdate = useEventStore(s => s.event);
 43  const setIsEditing = useEventStore(s => s.setIsEditing);
 44  const [updateEvent] = useUpdateEventMutation();
 45  const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
 46  const [openNewCar, toggleNewCar] = useReducer(i => !i, false);
 47  const {data: {eventByUUID: event} = {}} = useEventByUuidQuery({
 48    pollInterval: POLL_INTERVAL,
 49    variables: {uuid: eventUUID},
 50  });
 51
 52  useEffect(() => {
 53    if (event) setEvent(event as EventType);
 54  }, [event]);
 55
 56  const onSave = async e => {
 57    try {
 58      const {uuid, ...data} = eventUpdate;
 59      delete data.id;
 60      delete data.__typename;
 61      delete data.cars;
 62      delete data.waitingList;
 63      await updateEvent({
 64        variables: {uuid, eventUpdate: data},
 65        refetchQueries: ['eventByUUID'],
 66      });
 67      setIsEditing(false);
 68    } catch (error) {
 69      console.error(error);
 70      addToast(t('event.errors.cant_update'));
 71    }
 72  };
 73
 74  const onShare = async () => {
 75    if (!event) return null;
 76    // If navigator as share capability
 77    if (!!navigator.share)
 78      return await navigator.share({
 79        title: `Caroster ${event.name}`,
 80        url: `${window.location.href}`,
 81      });
 82    // Else copy URL in clipboard
 83    else if (!!navigator.clipboard) {
 84      await navigator.clipboard.writeText(window.location.href);
 85      addToast(t('event.actions.copied'));
 86      return true;
 87    }
 88  };
 89
 90  if (!event) return <Loading />;
 91
 92  return (
 93    <Layout
 94      pageTitle={t('event.title', {title: event.name})}
 95      menuTitle={t('event.title', {title: event.name})}
 96      displayMenu={false}
 97    >
 98      <EventBar
 99        event={event}
100        onAdd={setIsAddToMyEvent}
101        onSave={onSave}
102        onShare={onShare}
103      />
104      <CarColumns toggleNewCar={toggleNewCar} />
105      <Fab onClick={toggleNewCar} open={openNewCar} aria-label="add-car" />
106      <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
107      <AddToMyEventDialog
108        event={event}
109        open={isAddToMyEvent}
110        onClose={() => setIsAddToMyEvent(false)}
111      />
112    </Layout>
113  );
114};
115
116export async function getServerSideProps(ctx) {
117  const {uuid} = ctx.query;
118  const apolloClient = initializeApollo();
119  const {data = {}} = await apolloClient.query({
120    query: EventByUuidDocument,
121    variables: {uuid},
122  });
123  const {eventByUUID: event} = data;
124  const {host = ''} = ctx.req.headers;
125
126  return {
127    props: {
128      event,
129      eventUUID: uuid,
130      metas: {
131        title: event?.name || '',
132        url: `https://${host}${ctx.resolvedUrl}`,
133      },
134    },
135  };
136}
137
138export default EventPage;